import pandas as pd
import tkinter as tk
from tkinter import filedialog, messagebox
import os
import yaml


def select_file():
    """打开文件选择对话框，让用户选择Excel文件路径

    Returns:
        str or None: 用户选择的文件路径，如果用户取消选择则返回None
    """
    file_path = filedialog.askopenfilename(
        title="请选择需转换的文件", filetypes=[("Excel files", "*.xlsx")]
    )
    if not file_path:
        messagebox.showwarning("警告", "未选择文件，程序将停止运行。")
        return None
    return file_path


def read_excel(file_path):
    """读取Excel文件并返回DataFrame

    Args:
        file_path (str): Excel文件的路径

    Returns:
        pandas.DataFrame or None: 读取的DataFrame，如果读取失败则返回None
    """
    try:
        return pd.read_excel(file_path)
    except Exception as e:
        messagebox.showerror("错误", f"读取文件时出错: {e}")
        return None


def process_data(df):
    """处理SCFI数据，提取航线和指数信息

    Args:
        df (pandas.DataFrame): 原始SCFI数据DataFrame

    Returns:
        tuple: (处理后的DataFrame, 数据变量)
               DataFrame包含航线和指数两列，数据变量为原始数据中的时间信息
    """
    # 提取第2行第二列的值作为数据变量
    data_variable = df.iloc[1, 1]
    print("数据变量：", data_variable)

    # 去除前六行的数据
    df = df.iloc[6:]
    print("去除前六行后的数据：")
    print(df.head())

    # 保留第一列和第四列的数据
    df = df.iloc[:, [0, 3]]
    print("保留第一列和第四列后的数据：")
    print(df.head())

    # 修改列名
    df.columns = ["航线", "指数"]
    print("修改列名后的数据：")
    print(df.head())

    # 将"航线"列转换为字符串
    df["航线"] = df["航线"].astype(str)

    # 找到并处理包含"版权所有"字符的行
    copyright_index = df[df["航线"].str.contains("版权所有")].index
    if not copyright_index.empty:
        df = df.loc[: copyright_index[0] - 1]

    # 删除包含"分航线"字符的行
    df = df[~df["航线"].str.contains("分航线")]
    print("删除包含'分航线'字符的行后的数据：")
    print(df.head())

    # 重置索引
    df.reset_index(drop=True, inplace=True)
    print("重置索引后的数据：")
    print(df.dtypes)

    return df, data_variable


def merge_data(df, df2, data_variable):
    """将处理后的数据与航线对照表合并

    Args:
        df (pandas.DataFrame): 处理后的SCFI数据，包含航线和指数列
        df2 (pandas.DataFrame): 航线对照表，包含航线和对照航线列
        data_variable: 时间信息

    Returns:
        pandas.DataFrame: 合并后的DataFrame，包含时间、航线和指数三列
    """
    df_merged = pd.merge(df, df2, on="航线", how="left")
    print("合并后的数据：")
    print(df_merged.dtypes)

    # 添加时间列
    df_merged["时间"] = data_variable
    print("添加'时间'列后的数据：")
    print(df_merged.dtypes)

    # 删除"航线"列并重新排列列
    df_merged.drop(columns=["航线"], inplace=True)
    df_merged = df_merged[["时间", "对照航线", "指数"]]
    df_merged.rename(columns={"对照航线": "航线"}, inplace=True)

    # 将"指数"列的格式改为数值
    df_merged["指数"] = pd.to_numeric(df_merged["指数"], errors="coerce")
    print("将'指数'列的格式改为数值后的数据：")
    print(df_merged.dtypes)

    return df_merged


def save_to_excel(df_merged, data_variable):
    """将合并后的DataFrame保存为Excel文件

    Args:
        df_merged (pandas.DataFrame): 合并后的数据
        data_variable: 时间信息，用于文件命名

    Returns:
        str: 保存的文件路径
    """
    # 创建输出目录（如果不存在）
    output_dir = os.path.join(os.path.dirname(__file__), "output")
    os.makedirs(output_dir, exist_ok=True)
    output_file_path = os.path.join(output_dir, f"merged_scfi_data_{data_variable}.xlsx")
    df_merged.to_excel(output_file_path, index=False)
    return output_file_path


def open_folder(path):
    """打开指定路径的文件夹

    Args:
        path (str): 文件路径，将打开该文件所在的目录
    """
    os.startfile(os.path.dirname(path))


def show_completion_window(output_file_path):
    """显示文件转换完成的窗口，提供打开文件夹选项

    Args:
        output_file_path (str): 输出文件的路径
    """
    completion_window = tk.Tk()
    completion_window.title("完成")
    completion_window.geometry("300x100")

    # 设置窗口关闭事件处理
    def on_closing():
        completion_window.destroy()
        root.destroy()
        exit()

    completion_window.protocol("WM_DELETE_WINDOW", on_closing)

    label = tk.Label(completion_window, text="文件转换已完成！")
    label.pack(pady=10)

    button = tk.Button(
        completion_window,
        text="打开文件夹",
        command=lambda: [open_folder(output_file_path), completion_window.destroy(), root.destroy(), exit()],
    )
    button.pack(pady=5)

    completion_window.mainloop()


if __name__ == "__main__":
    # 创建一个隐藏的Tkinter根窗口
    root = tk.Tk()
    root.withdraw()

    # 选择文件并读取数据
    file_path = select_file()
    if file_path is None:
        root.destroy()
        exit()

    df = read_excel(file_path)
    if df is None:
        root.destroy()
        exit()

    # 处理数据
    df, data_variable = process_data(df)

    # 读取YAML格式的航线对照表配置
    yaml_file_path = os.path.join(os.path.dirname(__file__), "scfi_route_mapping.yaml")
    with open(yaml_file_path, 'r', encoding='utf-8') as f:
        route_mapping = yaml.safe_load(f)
    
    # 创建对照表DataFrame
    df2 = pd.DataFrame(list(route_mapping.items()), columns=["航线", "对照航线"])

    # 合并数据
    df_merged = merge_data(df, df2, data_variable)

    # 保存合并后的数据
    output_file_path = save_to_excel(df_merged, data_variable)

    # 显示完成窗口
    show_completion_window(output_file_path)
